from fastapi import FastAPI, Query, Body, Depends, Header
from pydantic import BaseModel, Field
from typing import Union, Literal, Annotated
import logging
from middle import request_headers

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S', encoding='utf-8')

app = FastAPI()

async def get_request_header():
    return request_headers

class CommonHeaders(BaseModel):
    user_agent: str = Field(default="", description="User-Agent")
    x_token: str = Field(default="", description="X-Token")

@app.get("/")
async def root(user_agent: Annotated[str | None, Header()] = None):
    logging.info(user_agent)
    return {"message": "Hello World222", "user_agent": user_agent}
@app.get("/item/{id}")
async def get_one(id: int, headers: Annotated[CommonHeaders, Header()]):
    logging.info("get one:"+str(id))
    return {"id": id, "headers": headers}
@app.get("/items")
async def get_list(q = None, page: int=1, page_size: int=10):
    logging.info("get list:"+str(page)+","+str(page_size))
    return {"page": page, "page_size": page_size, "q": q}
# 请求体
class User(BaseModel):
    name: str
    age: int
    tax: float | None = None
@app.post("/user")
async def create_user(user: User) -> User:
    logging.info("create user:"+str(user))
    return user
# @app.put("/user/{id}")
# async def update_user(id: int, user: User) -> User:
#     logging.info("update user:"+str(id)+","+str(user))
#     return user
@app.get("/some_user")
async def get_some_user(q: Union[str, None] = Query(default=None, max_length=20)):
    logging.info("get some user"+str(q)+str(type(q)))
    return {"name": "some user", "age": 18}

# 参数验证模型
class FilterParams(BaseModel):
    limit: int = Field(default=10, ge=1, le=100) # 限制范围, ge:大于等于, le:小于等于
    page: int = Field(default=1, ge=1) # 分页 , ge:大于等于, le:小于等于
    orderBy: Literal["created_at", "updated_at"] = "created_at" # 排序, Literal:枚举类型
    tags: list[str] = [] # 标签，list[str]
@app.get("/filter")
async def filter_user(params: Annotated[FilterParams, Body()]):
    logging.info("filter user:"+str(params))
    return {"params": params}
@app.put("/user/{id}")
async def update_user(id: int, user: User, params: Annotated[FilterParams, Body()]):
    logging.info("update user:"+str(id)+","+str(user)+","+str(params))
    return {"user": user, "params": params}